<template>
  <div class="app-container">

    <el-row :gutter="20">

      <!--菜单权限树-->
      <el-col :span="8">
        <el-card class="box-card">
          <div slot="header">
            <div class="title-box">
              <span>
                <el-tag type="success">菜单</el-tag>&nbsp;权限元数据
              </span>
              <el-tooltip content="同步菜单权限数据" placement="top">
                <el-button style="font-size: 25px;" type="text" @click="handleSyncMenuPermissionData" icon="el-icon-refresh" circle></el-button>
              </el-tooltip>
            </div>
            <span class="tips-text">提示：菜单权限由页面路由定义，不提供任何编辑功能，只能执行将权限数据同步到数据库的操作。
              菜单权限值建议使用前缀&nbsp;<el-tag size="mini" type="success">m:</el-tag>
            </span>
          </div>
          <el-input class="mgb-15" :placeholder="filterPlaceholderText" v-model="filterMenuPermText"></el-input>
          <el-tree ref="menuPermTreeRef" :filter-node-method="filterNode" :data="menuPermissionTree" :props="treeProps" node-key="pval" default-expand-all :expand-on-click-node="false">
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>
                <span class="mgl-10">{{ data.pname }}</span>
                <span class="mgl-10 tips-text">{{ data.pval }}</span>
                <el-tag class="mgl-10" type="success" size="mini">菜单</el-tag>
                <el-tag v-if="!menuPermValSet.has(data.pval)" class="mgl-10" type="danger" size="mini">未同步</el-tag>
              </span>
            </span>
          </el-tree>
        </el-card>
      </el-col>
    </el-row>

  </div>
</template>

<script>
import tree from './tree'
// import { resetTemp } from '@/utils'
import permApi from '@/api/perm'
import { permType } from '@/utils/constants'
// import {asyncRouterMap} from '@/router' //路由表，定义了菜单和按钮的元数据，可以用来生成权限控制的菜单按钮树
import debounce from 'lodash/debounce'

export default {
  name: 'PermManage',
  data() {
    return {
      btnPermPrefix: 'b:',
      filterPlaceholderText: '输入权限名称、权限值过滤',
      menuPermValSet: new Set(),
      apiPermValSet: new Set(),
      btnPermMap: {}, // 按parent字段分组的map
      menuPermissionTree: [], // 菜单权限树
      buttonPermissionTree: [], // 菜单权限树
      apiPermissionTree: [], // 菜单权限树

      filterMenuPermText: '',
      filterButtonPermText: '',
      filterApiPermText: '',

      permType,

      treeProps: {
        label: 'pname',
        children: 'children'
      },

      dialogFormVisible: false,
      dialogStatus: '',
      textMap: {
        // addButton: '添加按钮权限',
        updateButton: '更新按钮权限',
        deleteButton: '删除按钮权限'
      },
      temp: {
        idx: null,
        pid: null,
        pname: null,
        ptype: null,
        pval: null,
        leaf: null,
        parent: null
      },
      rules: {
        pname: [{ required: true, message: '必填', trigger: 'blur' }],
        ptype: [{ required: true, message: '必填', trigger: 'blur' }],
        pval: [{ required: true, message: '必填', trigger: 'change' }]
      }
    }
  },
  watch: {
    filterMenuPermText: debounce(function(val) {
      this.$refs.menuPermTreeRef.filter(val)
    }, 600),
    filterButtonPermText: debounce(function(val) {
      this.$refs.buttonPermTreeRef.filter(val)
    }, 600),
    filterApiPermText: debounce(function(val) {
      this.$refs.apiPermTreeRef.filter(val)
    }, 600)
  },

  created() {
    this.initData()
  },

  methods: {
    // 获取后台权限数据
    initData() {
      permApi.listAllPermissions().then(res => {
        // 按parent分组的按钮权限
        this.btnPermMap = res.data.btnPermMap || {}
        // 含有所有权限map，key是ptype
        const permMap = res.data.permMap || {}
        // 后台存储的所有菜单权限，用于比较前后台数据是否同步
        const menuPermList = permMap[permType.MENU] || []
        this.menuPermValSet = new Set(menuPermList.map(p => p.pval))
        // 后台存储的所有接口权限，用于比较数据是否同步
        // const apiPermList = permMap[permType.API] || []
        // this.apiPermValSet = new Set(apiPermList.map(p => p.pval))
        // 显示菜单权限树
        this.menuPermissionTree = tree.generateMenuPermissionTree()
        // 显示按钮权限树
        // const menuPermissionTreeCopy = tree.generateMenuPermissionTree()
        // this.buttonPermissionTree = this.generateButtonPermissionTree(menuPermissionTreeCopy)
        // 显示接口权限树
        // this.loadApiButtonPermissionTree()
      })
    },

    /**
     * 过滤节点
     */
    filterNode(value, data) {
      if (!value) return true
      return data.pname.indexOf(value) !== -1 || data.pval.indexOf(value) !== -1
    },

    /**
     * 递归生成按钮权限树
     */
    generateButtonPermissionTree(menuPermissionTreeCopy) {
      return tree.mapToButtonPermissionTree(this.btnPermMap, menuPermissionTreeCopy)
    },
    // 普通用户修改密码的页面和接口！！！！

    /**
     * 同步菜单权限数据
     */
    handleSyncMenuPermissionData() {
      const list = []
      this.permissionTreeToList(list, this.menuPermissionTree)
      permApi.syncMenuPerms(list).then(res => {
        this.initData()
        this.$message.success('菜单权限数据同步成功')
      })
    },

    /**
     * 菜单权限树转换成列表形式
     */
    permissionTreeToList(list, tree) {
      tree.forEach(perm => {
        const temp = Object.assign({}, perm)
        temp.children = []
        if (perm.children && perm.children.length > 0) {
          temp.leaf = false
          this.permissionTreeToList(list, perm.children)
        } else {
          temp.leaf = true
        }
        list.push(temp)
      })
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.text {
  font-size: 14px;
}

.item {
  margin-bottom: 18px;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: '';
}

.clearfix:after {
  clear: both;
}

.box-card {
  width: 100%;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.card-title {
  line-height: 50px;
  height: 50px;
}

.tips-text {
  font-size: 14px;
  color: #909399;
}

.title-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
  span {
    font-size: 22px;
  }
}

.update-btn {
  margin-left: 20px;
}

.delete-btn {
  margin-left: 20px;
  color: #f56c6c;
}

.mgl-10 {
  margin-left: 10px;
}

.mgb-15 {
  margin-bottom: 15px;
}
</style>
